<template>
  <div ref="scrollWrapperRef" :style="{ height: px2vmin(height) }">
    <slot></slot>
  </div>
</template>

<script lang="ts" setup>
import BScroll from '@better-scroll/core'
import PullUp from '@better-scroll/pull-up'
import PullDown from '@better-scroll/pull-down'
import ObserveDOM from '@better-scroll/observe-dom'
import { usePlayerStore } from '@/stores/playerStore'
import { px2vmin } from '@/utils'
// 注册BScroll功能插件
BScroll.use(PullUp)
BScroll.use(PullDown)
BScroll.use(ObserveDOM)
const playerStore = usePlayerStore()
const scroll = ref<BScroll>()
const scrollWrapperRef = ref<HTMLDivElement | null>(null)
const emits = defineEmits<{
  (e: 'scroll', pos: IPos): void
  (e: 'pullingDown', scroll: BScroll | undefined): void
  (e: 'pullingUp', scroll: BScroll | undefined): void
}>()

interface IProps {
  click?: boolean
  probeType?: number
  scrollY?: boolean
  scrollX?: boolean
  bounce?: boolean
  height: number
  pullDownRefresh?: boolean
  pullUpLoad?: boolean
  threshold?: number
  stop?: number
}
const props = withDefaults(defineProps<IProps>(), {
  scrollY: true,
  scrollX: false,
  click: true,
  probeType: 3,
  bounce: true,
  height: 0,
  pullDownRefresh: false,
  pullUpLoad: false,
  threshold: 90,
  stop: 56
})
onMounted(async () => {
  let scrollVal = scroll.value
  if (!scrollVal) {
    if (scrollWrapperRef.value !== null) {
      const {
        probeType,
        click,
        scrollY,
        scrollX,
        bounce,
        pullDownRefresh,
        pullUpLoad,
        threshold,
        stop
      } = props
      scroll.value = scrollVal = new BScroll(scrollWrapperRef.value, {
        observeDOM: true,
        click,
        probeType,
        [scrollX ? 'scrollX' : 'scrollY']: scrollX ? scrollX : scrollY,
        [pullDownRefresh ? 'pullDownRefresh' : '']: {
          threshold,
          stop
        },
        [pullUpLoad ? 'pullUpLoad' : '']: pullUpLoad,
        bounce
      })
      if (probeType > 0) {
        scrollVal?.on('scroll', (pos: IPos) => {
          emits('scroll', pos)
        })
      }
      if (pullDownRefresh) {
        scrollVal?.on('pullingDown', () => {
          emits('pullingDown', scrollVal)
        })
      }
      if (pullUpLoad) {
        scrollVal?.on('pullingUp', () => {
          emits('pullingUp', scrollVal)
        })
      }
    }
  } else if (scrollVal instanceof BScroll) {
    scrollVal.refresh()
  }
})
watch(
  () => playerStore.playlist,
  async () => {
    await nextTick()
    refresh()
  }
)
watch(
  () => props.height,
  async () => {
    await nextTick()
    refresh()
  }
)
function refresh() {
  scroll.value?.refresh()
}
function scrollToElement(ele: HTMLElement) {
  scroll.value?.scrollToElement(ele, 300, false, false)
}
defineExpose({
  scroll,
  refresh,
  scrollToElement
})
</script>
<style scoped lang="scss"></style>
